






















package record;

import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.Toast;

import com.qingning.qn.R;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import base.BaseActivity;
import io.imgselector.FlutterNativeImgPlugin;


public class RecordVideoActivity extends BaseActivity implements SurfaceHolder.Callback, MediaRecorder.OnErrorListener, View.OnClickListener {
    // setVideoSize     setFixedSize    setPreviewSize
    SurfaceView surfaceView;
    ImageView imgFB;
    ImageView mRecordControl;
    Chronometer mRecordTime;

    private SurfaceHolder mSurfaceHolder;
    private boolean isRecording; // 标记，判断当前是否正在录制

    int cameraType = 0;
    int cameraFlag = 1; //1为后置
    int frontRotate;    //旋转的角度
    int frontOri;       //录制下来的视屏选择角度

    // 存储文件
    private File mVecordFile;
    private Camera mCamera;
    private MediaRecorder mediaRecorder;

    public final static int SIZE_1 = 640;
    public final static int SIZE_2 = 480;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record_video);
        initView();
        addListener();
    }


    public void initView() {
        surfaceView = (SurfaceView) findViewById(R.id.sv);
        imgFB = (ImageView) findViewById(R.id.imgFB);
        mRecordControl = (ImageView) findViewById(R.id.img);
        mRecordTime = (Chronometer) findViewById(R.id.time);

        //配置SurfaceHodler
        mSurfaceHolder = surfaceView.getHolder();
        // 设置Surface不需要维护自己的缓冲区
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // 设置分辨率
        mSurfaceHolder.setFixedSize(320, 280);
        // 设置该组件不会让屏幕自动关闭
        mSurfaceHolder.setKeepScreenOn(true);
        mSurfaceHolder.addCallback(this); //相机创建回调接口
    }


    public void addListener() {
        imgFB.setOnClickListener(this);
        mRecordControl.setOnClickListener(this);

        mRecordTime.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
            @Override
            public void onChronometerTick(Chronometer chronometer) {
                String time = chronometer.getText().toString();
                if ("00:11".equals(time)) {
                    // 最大时长10秒
                    Toast.makeText(RecordVideoActivity.this, "最大时长10秒", Toast.LENGTH_SHORT).show();
                    //停止视频录制
                    stopRecord();
                    releaseCamera();
                    endRecordUI();
                    startPlay();
                    mRecordTime.setText("00:00");
                }
            }
        });
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.imgFB:
                //切换前后摄像头
                switchCamera();
                break;
            case R.id.img:
                if (!isRecording) {
                    //开始录制视频
                    startRecord();
                    startRecordUI();
                } else {
                    //停止视频录制
                    String timeStr = mRecordTime.getText().toString();
                    int videoTime = Integer.valueOf(timeStr.substring(timeStr.indexOf(":") + 1));
                    stopRecord();
                    releaseCamera();
                    endRecordUI();
                    // 当前视频地址带到预览视频界面
                    startPlay();
                    mRecordTime.setText("00:00");
                }
                break;
        }
    }

    /**
     * 跳转预览界面
     */
    private void startPlay() {
        Intent intent = new Intent(this, PlayerVideoActivity.class);
        intent.putExtra("videoPath", mVecordFile.getAbsolutePath());
        startActivityForResult(intent, 201);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode != 201)
            return;
        if (resultCode == RESULT_OK) {
            Log.e("dafaf",mVecordFile.getAbsolutePath());
            // 选择中录制的视频
            Intent intent = new Intent();
            ArrayList<String> filePath=new ArrayList<>();
            filePath.add(mVecordFile.getAbsolutePath());
            intent.putStringArrayListExtra("file",filePath);
            System.out.println("这是要传递的");
            System.out.println(filePath);
            if(FlutterNativeImgPlugin.result!=null){
                FlutterNativeImgPlugin.result.success(filePath);
            }
//            intent.putExtra("file", mVecordFile.getAbsolutePath());
//            setResult(RESULT_OK, intent);
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isRecording) {
            stopRecord();
            endRecordUI();
            if (mCamera != null) {
                releaseCamera();
            }
            if (mRecordTime != null) {
                mRecordTime.stop();
                mRecordTime.setBase(SystemClock.elapsedRealtime());//计时器清零
            }
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        try {
            if (isRecording) {
                stopRecord();
                endRecordUI();
                if (mCamera != null) {
                    releaseCamera();
                }
                if (mRecordTime != null) {
                    mRecordTime.stop();
                    mRecordTime.setBase(SystemClock.elapsedRealtime());//计时器清零
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        onPause();
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        initCamera(cameraType);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        if (mSurfaceHolder.getSurface() == null) {
            return;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        releaseCamera();
    }

    /**
     * 初始化相机
     *
     * @param type 前后的类型
     */
    private void initCamera(int type) {
        if (mCamera != null) {
            //如果已经初始化过，就先释放
            releaseCamera();
        }
        try {
            mCamera = Camera.open(type);
            if (mCamera == null) {
                Toast.makeText(this, "未检测到摄像头", Toast.LENGTH_SHORT).show();
                return;
            }
            mCamera.lock();

            //Point screen = new Point(getScreenWidth(this), getScreenHeight(this));
            //现在不用获取最高的显示效果
            //Point show = getBestCameraShow(camera.getParameters(), screen);

            Camera.Parameters parameters = mCamera.getParameters();
            if (type == 0) {
                //基本是都支持这个比例
                parameters.setPreviewSize(SIZE_1, SIZE_2);
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//1连续对焦
                mCamera.cancelAutoFocus();// 2如果要实现连续的自动对焦，这一句必须加上
            }
            mCamera.setParameters(parameters);
            if (cameraType == 1) {
                frontCameraRotate();
                mCamera.setDisplayOrientation(frontRotate);
            } else {
                mCamera.setDisplayOrientation(90);
            }
            mCamera.setPreviewDisplay(mSurfaceHolder);
            mCamera.startPreview();
            mCamera.unlock();
        } catch (Exception e) {
            e.printStackTrace();
            releaseCamera();
        }
    }

    /**
     * 释放摄像头资源
     */
    private void releaseCamera() {
        try {
            if (mCamera != null) {
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
                mCamera.lock();
                mCamera.release();
                mCamera = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 旋转前置摄像头为正的
     */
    private void frontCameraRotate() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(1, info);
        int degrees = getDisplayRotation(this);
        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
        } else { // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        frontOri = info.orientation;
        frontRotate = result;
    }

    /**
     * 获取旋转角度
     */
    private int getDisplayRotation(Activity activity) {
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        switch (rotation) {
            case Surface.ROTATION_0:
                return 0;
            case Surface.ROTATION_90:
                return 90;
            case Surface.ROTATION_180:
                return 180;
            case Surface.ROTATION_270:
                return 270;
        }
        return 0;
    }


    /**
     * 开始录制时候的状态
     */
    private void startRecordUI() {
        imgFB.setVisibility(View.GONE); // 旋转摄像头关闭
        mRecordControl.setSelected(true);//录制按钮变成待停止
    }

    /**
     * 停止录制时候的状态
     */
    private void endRecordUI() {
        imgFB.setVisibility(View.VISIBLE); // 旋转摄像头关闭
        mRecordControl.setSelected(false); //录制按钮变成待停止
    }

    /**
     * 开始录制视频
     */
    public void startRecord() {
        boolean creakOk = createRecordDir();
        if (!creakOk) {
            return;
        }

        //懒人模式，根据闪光灯和摄像头前后重新初始化一遍，开期闪光灯工作模式
        initCamera(cameraType);

        if (mediaRecorder == null) {
            mediaRecorder = new MediaRecorder();
        }

        mediaRecorder.reset();
        mediaRecorder.setCamera(mCamera);
        mediaRecorder.setOnErrorListener(this);

        //  这两项需要放在setOutputFormat之前
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  //设置采集图像
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);    //设置采集声音
        //设置视频，音频的输出格式 mp4
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

        //音频一秒钟包含多少数据位  在setEncoder之前
        CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
        mediaRecorder.setAudioEncodingBitRate(44100);
        if (mProfile.videoBitRate > 2 * 1024 * 1024)
            mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
        else
            mediaRecorder.setVideoEncodingBitRate(1024 * 1024);
        mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);


        // 这两项需要放在setOutputFormat之后
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);      //3.设置音频的编码格式
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);     //设置图像的编码格式

        // 设置视频录制的分辨率。必须放在设置编码和格式的后面，否则报错
//        mediaRecorder.setVideoSize(288, 352);
        mediaRecorder.setVideoSize(352, 288);
        // 设置视频录制的分辨率。必须放在设置编码和格式的后面，否则报错

        //设置立体声
//        mediaRecorder.setAudioChannels(2);
        //设置最大录像时间 单位：毫秒
//        mediaRecorder.setMaxDuration(60 * 1000);
        //设置最大录制的大小 单位，字节
//        mediaRecorder.setMaxFileSize(1024 * 1024);


        //设置选择角度，顺时针方向，因为默认是逆向90度的，这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
        mediaRecorder.setOrientationHint(90);

        //使用SurfaceView预览
        mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
        //设置创建好的输入路径
        mediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());
        try {
            //开始录制
            mediaRecorder.prepare();
            mediaRecorder.start();
            isRecording = true;
        } catch (IOException e) {
            e.printStackTrace();
        }

        mRecordTime.setBase(SystemClock.elapsedRealtime());
        mRecordTime.start();
    }

    /**
     * 停止录制视频
     */
    public void stopRecord() {
        try {
            if (isRecording && mediaRecorder != null) {
                // 设置后不会崩
                mediaRecorder.setOnErrorListener(null);
                mediaRecorder.setPreviewDisplay(null);
                //停止录制
                mediaRecorder.stop();
                mediaRecorder.reset();
                //释放资源
                mediaRecorder.release();
                mediaRecorder = null;
                mRecordTime.stop();
                isRecording = false;
            }
        }catch (Exception e){

        }

    }

    /**
     * 创建视频文件保存路径
     */
    private boolean createRecordDir() {
        if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            Toast.makeText(this, "请查看您的SD卡是否存在！", Toast.LENGTH_SHORT).show();
            return false;
        }

        File sampleDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Record");
        if (!sampleDir.exists()) {
            sampleDir.mkdirs();
        }
        String recordName = "VID_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4";
        mVecordFile = new File(sampleDir, recordName);
        return true;
    }

    @Override
    public void onError(MediaRecorder mediaRecorder, int i, int i1) {
        try {
            if (mediaRecorder != null) {
                mediaRecorder.reset();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 切换摄像头
     */
    public void switchCamera() {
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数0或者1;

        try {
            for (int i = 0; i < cameraCount; i++) {
                Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
                if (cameraFlag == 1) {
                    //后置到前置
                    if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位，CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                        frontCameraRotate();//前置旋转摄像头度数
                        switchCameraLogic(i, 0, frontRotate);
                        break;
                    }
                } else {
                    //前置到后置
                    if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位，CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                        switchCameraLogic(i, 1, 90);
                        break;
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /***
     * 处理摄像头切换逻辑
     *
     * @param i           哪一个，前置还是后置
     * @param flag        切换后的标志
     * @param orientation 旋转的角度
     */
    private void switchCameraLogic(int i, int flag, int orientation) {
        if (mCamera != null) {
            mCamera.lock();
        }
        endRecordUI();
        releaseCamera();
        mCamera = Camera.open(i);//打开当前选中的摄像头
        try {
            mCamera.setDisplayOrientation(orientation);
            mCamera.setPreviewDisplay(mSurfaceHolder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        cameraFlag = flag;
        mCamera.startPreview();
        cameraType = i;
        mCamera.unlock();
    }
}

























